package com.ssy.lingxi.member.merchant.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Set;

/**
 * 会员上下级关系数据库DO
 * @author 万宁
 * @version 2.0.0
 * @date 2020-08-18
 */
@Entity
@Table(schema = "public", name = "ms_mc_member_relation", indexes = {@Index(name="ms_mc_member_relation_member_id_idx", columnList = "memberId"),@Index(name="ms_mc_member_relation_role_id_idx", columnList = "roleId"), @Index(name="ms_mc_member_relation_upper_member_id_idx", columnList = "upper_member_id"),@Index(name="ms_mc_member_relation_upper_role_id_idx", columnList = "upper_role_id"), @Index(name="ms_mc_member_relation_sub_member_id_idx", columnList = "subMemberId"), @Index(name="ms_mc_member_relation_sub_role_id_idx", columnList = "subRoleId"), @Index(name="ms_mc_member_relation_lower_member_id_idx", columnList = "lower_member_id"), @Index(name="ms_mc_member_relation_lower_role_id_idx", columnList = "lower_role_id"), @Index(name="ms_mc_member_relation_sub_role_name_idx", columnList = "subRoleName"), @Index(name="ms_mc_member_relation_rel_type_idx", columnList = "relType"), @Index(name="ms_mc_member_relation_sub_member_type_enum_idx", columnList = "subMemberTypeEnum"), @Index(name="ms_mc_member_relation_status_idx", columnList = "status"), @Index(name="ms_mc_member_relation_validate_outer_status_idx", columnList = "outerStatus"), @Index(name="ms_mc_member_relation_verified_idx", columnList = "verified"), @Index(name="ms_mc_member_relation_rel_source_idx", columnList = "relSource")})
public class MemberRelationDO implements Serializable {
    private static final long serialVersionUID = 5549145475208044955L;

    /**
     * 主键id
     */
    @Id
    @GeneratedValue(strategy= GenerationType.SEQUENCE, generator="member_relation_seq")
    @SequenceGenerator(sequenceName="ms_mc_member_relation_seq", name="member_relation_seq",allocationSize = 1)
    private Long id;

    /**
     * 创建时间（注册时间）
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime createTime;

    /**
     * 上级会员Id
     */
    @Column
    private Long memberId;

    /**
     * 上级会员，多对一单向关联
     */
    @JsonManagedReference
    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "upper_member_id", referencedColumnName = "id")
    private MemberDO member;

    /**
     * 上级会员角色Id
     */
    @Column
    private Long roleId;

    /**
     * 上级会员角色
     */
    @JsonManagedReference
    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "upper_role_id", referencedColumnName = "id")
    private RoleDO role;

    /**
     * 上级会员的用户Id
     */
    @Column
    private Long userId;

    /**
     * 下级会员Id
     */
    @Column
    private Long subMemberId;

    /**
     * 下级会员， 多对一单向关联
     */
    @JsonBackReference
    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "lower_member_id", referencedColumnName = "id")
    private MemberDO subMember;

    /**
     * 下级会员角色Id
     */
    @Column
    private Long subRoleId;

    /**
     * 下级会员角色
     */
    @JsonBackReference
    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "lower_role_id", referencedColumnName = "id")
    private RoleDO subRole;

    /**
     * 下级会员的用户Id
     */
    @Column
    private Long subUserId;

    /**
     * 下级会员角色名称
     */
    @Column(columnDefinition = "varchar(50)")
    private String subRoleName;

    /**
     * 下级会员的会员类型枚举，定义在MemberTypeEnum和MemberTypeDO中
     */
    @Column(columnDefinition = "int")
    private Integer subMemberTypeEnum;

    /**
     * 下级会员的等级类型，定义在MemberLevelTypeEnum中
     */
    @Column(columnDefinition = "int")
    private Integer subMemberLevelTypeEnum;

    /**
     * 标识字段，定义在MemberRelationTypeEnum中，0-上级会员是平台 1-上级会员不是平台
     */
    @Column(columnDefinition = "int")
    private Integer relType;

    /**
     * 标识字段，定义在MemberRelationSourceEnum中，0-通过Web注册，1-通过移动端注册，2-通过新增角色成为下级会员，3-通过平台后台创建，4-通过会员能力创建，5-通过主动申请成为下级会员
     */
    @Column(columnDefinition = "int")
    private Integer relSource;

    /**
     * 下级会员审核内部状态
     */
    @Column(columnDefinition = "int")
    private Integer innerStatus;

    /**
     * 下级会员审核外部状态
     */
    @Column(columnDefinition = "int")
    private Integer outerStatus;

    /**
     * 是否（曾经）审核通过，0-否，1-是，定义在MemberValidateStatusEnum中。此字段用于注册资料、入库资料的修改判断
     * <p>在平台会员审核通过后，将外部状态设置为通过、此字段设置为1</p>
     * <p>在会员能力审核通过后，将内部状态设置为通过，此字段设置为1</p>
     * <p>对于平台会员，此字段还表示曾经审核通过过，在会员登录的时候进行判断</p>
     */
    @Column
    private Integer verified;

    /**
     * 如果审核不通过，最后一次的审核意见
     */
    @Column(columnDefinition = "varchar(255)")
    private String validateMsg;

    /**
     * 下级会员状态
     */
    @Column(columnDefinition = "int")
    private Integer status;

    /**
     * 一对一单向关联渠道信息（当subMemberTypeEnum为渠道会员、渠道个人会员时不为Null）
     */
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="member_channel_id",referencedColumnName="id")
    private MemberChannelDO channel;

    /**
     * 入库时间，平台会员、商户会员审核通过后，要填写此字段
     */
    @Column(columnDefinition = "timestamp")
    private LocalDateTime depositTime;

    /**
     * 一对多双向关联入库资料
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "relation", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberDepositoryDetailDO> depositDetails;

    /**
     * 一对多双向关联会员资质文件
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "relation", cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<MemberQualityDO> qualities;

    /**
     * 一对一双向关联会员分类信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.DETACH, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="classification_id",referencedColumnName="id")
    private MemberClassificationDO classification;

    /**
     * 一对一单向关联审核任务
     */
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="validate_task_id",referencedColumnName="id")
    private MemberValidateTaskDO validateTask;

    /**
     * 一对一双向关联下级会员权限
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="relation_auth_id",referencedColumnName="id")
    private MemberRelationAuthDO relationAuth;

    /**
     * 一对一双向关联会员等级积分信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="level_right_id",referencedColumnName="id", foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT))
    private MemberLevelRightDO levelRight;

    /**
     * 一对一双向关联会员信用信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    @JoinColumn(name="credit_id",referencedColumnName="id", foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT))
    private MemberCreditDO credit;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public Long getMemberId() {
        return memberId;
    }

    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }

    public MemberDO getMember() {
        return member;
    }

    public void setMember(MemberDO member) {
        this.member = member;
    }

    public Long getRoleId() {
        return roleId;
    }

    public void setRoleId(Long roleId) {
        this.roleId = roleId;
    }

    public RoleDO getRole() {
        return role;
    }

    public void setRole(RoleDO role) {
        this.role = role;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Long getSubMemberId() {
        return subMemberId;
    }

    public void setSubMemberId(Long subMemberId) {
        this.subMemberId = subMemberId;
    }

    public MemberDO getSubMember() {
        return subMember;
    }

    public void setSubMember(MemberDO subMember) {
        this.subMember = subMember;
    }

    public Long getSubRoleId() {
        return subRoleId;
    }

    public void setSubRoleId(Long subRoleId) {
        this.subRoleId = subRoleId;
    }

    public RoleDO getSubRole() {
        return subRole;
    }

    public void setSubRole(RoleDO subRole) {
        this.subRole = subRole;
    }

    public Long getSubUserId() {
        return subUserId;
    }

    public void setSubUserId(Long subUserId) {
        this.subUserId = subUserId;
    }

    public String getSubRoleName() {
        return subRoleName;
    }

    public void setSubRoleName(String subRoleName) {
        this.subRoleName = subRoleName;
    }

    public Integer getSubMemberTypeEnum() {
        return subMemberTypeEnum;
    }

    public void setSubMemberTypeEnum(Integer subMemberTypeEnum) {
        this.subMemberTypeEnum = subMemberTypeEnum;
    }

    public Integer getSubMemberLevelTypeEnum() {
        return subMemberLevelTypeEnum;
    }

    public void setSubMemberLevelTypeEnum(Integer subMemberLevelTypeEnum) {
        this.subMemberLevelTypeEnum = subMemberLevelTypeEnum;
    }

    public Integer getRelType() {
        return relType;
    }

    public void setRelType(Integer relType) {
        this.relType = relType;
    }

    public Integer getRelSource() {
        return relSource;
    }

    public void setRelSource(Integer relSource) {
        this.relSource = relSource;
    }

    public Integer getInnerStatus() {
        return innerStatus;
    }

    public void setInnerStatus(Integer innerStatus) {
        this.innerStatus = innerStatus;
    }

    public Integer getOuterStatus() {
        return outerStatus;
    }

    public void setOuterStatus(Integer outerStatus) {
        this.outerStatus = outerStatus;
    }

    public Integer getVerified() {
        return verified;
    }

    public void setVerified(Integer verified) {
        this.verified = verified;
    }

    public String getValidateMsg() {
        return validateMsg;
    }

    public void setValidateMsg(String validateMsg) {
        this.validateMsg = validateMsg;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public MemberChannelDO getChannel() {
        return channel;
    }

    public void setChannel(MemberChannelDO channel) {
        this.channel = channel;
    }

    public LocalDateTime getDepositTime() {
        return depositTime;
    }

    public void setDepositTime(LocalDateTime depositTime) {
        this.depositTime = depositTime;
    }

    public Set<MemberDepositoryDetailDO> getDepositDetails() {
        return depositDetails;
    }

    public void setDepositDetails(Set<MemberDepositoryDetailDO> depositDetails) {
        this.depositDetails = depositDetails;
    }

    public Set<MemberQualityDO> getQualities() {
        return qualities;
    }

    public void setQualities(Set<MemberQualityDO> qualities) {
        this.qualities = qualities;
    }

    public MemberClassificationDO getClassification() {
        return classification;
    }

    public void setClassification(MemberClassificationDO classification) {
        this.classification = classification;
    }

    public MemberValidateTaskDO getValidateTask() {
        return validateTask;
    }

    public void setValidateTask(MemberValidateTaskDO validateTask) {
        this.validateTask = validateTask;
    }

    public MemberRelationAuthDO getRelationAuth() {
        return relationAuth;
    }

    public void setRelationAuth(MemberRelationAuthDO relationAuth) {
        this.relationAuth = relationAuth;
    }

    public MemberLevelRightDO getLevelRight() {
        return levelRight;
    }

    public void setLevelRight(MemberLevelRightDO levelRight) {
        this.levelRight = levelRight;
    }

    public MemberCreditDO getCredit() {
        return credit;
    }

    public void setCredit(MemberCreditDO credit) {
        this.credit = credit;
    }
}
